﻿#include "videoframeprovider.h"
#include <QDebug>
#include <QElapsedTimer>

VideoFrameProvider::VideoFrameProvider(QObject *parent) : QObject(parent) {}

VideoFrameProvider::~VideoFrameProvider() {
    stopVideo();
}

void VideoFrameProvider::startVideo(const QString &filePath) {
    if (1 == m_running) return;

    m_running.store(1);
    m_paused.store(0);
    m_videoThread = QThread::create([this, filePath]() { videoThreadFunc(filePath); });
    m_videoThread->start();
    emit videoStarted();
}

void VideoFrameProvider::stopVideo() {
    if (1 != m_running) return;

    m_running.store(0);
    m_paused.store(0);
    m_condition.wakeAll();

    if (m_videoThread) {
        m_videoThread->wait();
        delete m_videoThread;
        m_videoThread = nullptr;
    }

    if (m_capture.isOpened()) {
        m_capture.release();
    }

    emit videoStopped();
}

void VideoFrameProvider::pauseVideo() {
    if(0 == m_paused.load()){
        m_paused.store(1);
    }
    else{
        m_paused.store(0);
    }

    if (0 == m_paused.load()) {
        m_condition.wakeAll();
    }
}

bool VideoFrameProvider::isPlaying() const {
    return 1 == m_running.load() &&  0 == m_paused.load();
}

void VideoFrameProvider::frameProcessed(){
    m_frameInUse.store(0);
}

void VideoFrameProvider::videoThreadFunc(const QString &filePath) {
    // 启用硬件加速
    m_capture.open(filePath.toStdString(), cv::CAP_FFMPEG);
    m_capture.set(cv::CAP_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_ANY);
    m_capture.set(cv::CAP_PROP_BUFFERSIZE, 3); // 限制缓冲区大小

    if (!m_capture.isOpened()) {
        qWarning() << "Failed to open video file:" << filePath;
        m_running.store(0);
        return;
    }

    cv::Mat frame;
    QElapsedTimer frameTimer;
    const int targetFps = qMax(1, static_cast<int>(m_capture.get(cv::CAP_PROP_FPS)));
    const int targetDelay = 1000 / targetFps;

    while (1 == m_running.load()) {
        if (1 == m_paused.load()) {
            QMutexLocker locker(&m_mutex);
            m_condition.wait(&m_mutex);
            continue;
        }

        // 等待前一帧处理完成
        while (m_frameInUse.load() > 0 && 1 == m_running.load()) {
            QThread::msleep(1);
        }

        frameTimer.restart();

        if (!m_capture.read(frame) || frame.empty()) {
            if (m_capture.get(cv::CAP_PROP_POS_FRAMES) >= m_capture.get(cv::CAP_PROP_FRAME_COUNT)) {
                m_capture.set(cv::CAP_PROP_POS_FRAMES, 0); // 循环播放
                continue;
            }
            break;
        }

        // 转换为RGB格式
        cv::Mat rgbFrame;
        cv::cvtColor(frame, rgbFrame, cv::COLOR_BGR2RGB);

        // 创建QImage并共享数据（不拷贝）
        QImage image(rgbFrame.data, rgbFrame.cols, rgbFrame.rows,
                     rgbFrame.step, QImage::Format_RGB888);

        m_frameInUse.store(1);
        emit newFrameAvailable(image.copy()); // 必须拷贝以避免数据竞争

        // 控制帧率
        int elapsed = frameTimer.elapsed();
        int remaining = targetDelay - elapsed;
        if (remaining > 0) {
            QThread::msleep(static_cast<unsigned long>(remaining));
        }
    }

    m_running.store(0);
    emit videoStopped();
}
